package cc.wanforme.st.server.authen.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cc.wanforme.st.server.authen.dto.AdminRoleAuth;
import cc.wanforme.st.server.authen.dto.UserRoleAuth;
import cc.wanforme.st.server.authen.service.TokenService;
import cc.wanforme.st.server.authen.service.AuthService;
import cc.wanforme.st.server.base.constant.UserType;
import cc.wanforme.st.server.base.service.IAdminService;
import cc.wanforme.st.server.base.service.IUserService;
import cc.wanforme.st.server.util.JwtUtil;

/** 记住我功能 service
 * @author wanne
 * 2020年10月23日
 */

public class MRememberMeFilter implements Filter{
	private static final Logger log = LoggerFactory.getLogger(MRememberMeFilter.class);
	private static final String AUTH_HEADER = "Authorization";
	
	private TokenService tokenService;
	private AuthService authService;
	private IAdminService adminService;
	private IUserService userService;
	
	public MRememberMeFilter(TokenService tokenService,
			AuthService authService, IAdminService adminService,
			IUserService userService) {
		this.tokenService = tokenService;
		this.authService = authService;
		this.adminService = adminService;
		this.userService = userService;
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		
		String token = getToken(req, tokenService);
		try {
			// 存在 token，并且未添加验证信息（注意：登录的时候，一定要先清除验证信息）
			if( token != null && !authService.isAuthenticated()) {
				// 管理员
				String type = JwtUtil.getType(token); 
				if(UserType.ADMIN.name().equals(type)) {
					AdminRoleAuth roleAuth = adminService.selectAuthenticationsByToken(token);
					authService.setAuthentications(roleAuth);
				} else if(UserType.USER.name().equals(type)) {
					// 普通用户 
					UserRoleAuth uRoleAuth = userService.selectAuthenticationsByToken(token);
					authService.setAuthentications(uRoleAuth);
				}
				
//				String host = req.getRemoteHost();
				
				// 检查 token 登陆地
//				AuthToken tokenInfo = tokenService.selectToken(token);
//				if( tokenInfo.getHost().equals(host) ) {
//					authService.setAuthentications(roleAuth);
//				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			tokenService.clearAuthentications((HttpServletResponse)response);
		}
		
		chain.doFilter(request, response);
	}

	/** 先从请求头 Authorization 中获取token，没有再查从 cookie 中找<br>
	 * 推荐将 token 放在请求头中，不要让程序从 cookie 中获取。
	 * 因为管理和用户已经分开，在管理和用户同时登录的情况下， cookie 会错乱。 
	 * @param request
	 * @param tokenService
	 * @return
	 */
	public static String getToken(HttpServletRequest request, TokenService tokenService) {
		String token = request.getHeader(AUTH_HEADER);
		if (token == null || "".equals(token.trim())) {
			token = tokenService.getTokenFromCookie(request);
		}
		return token;
	}
}
